package com.ants.modules.receiver;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import com.ants.common.utils.MinioUtil;
import com.ants.common.utils.RedisUtil;
import com.ants.modules.config.FreemarkerParseFactory;
import com.ants.modules.config.MailProperties;
import com.ants.modules.sendMail.entity.MailConfig;
import com.ants.modules.sendMail.entity.SendMailHistory;
import com.ants.modules.sendMail.service.MailConfigService;
import com.ants.modules.sendMail.service.SendMailHistoryService;
import com.ants.modules.sendMail.vo.SendMailVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * TODO   发送邮件
 * Author Chen
 * Date   2021/10/15 9:18
 */
//@RabbitListener(queues = "sendMailQueue")
@Component
@Slf4j
public class SendMailReceiver {

    @Value(value = "${ants.path.upload}")
    private String uploadpath;

    @Autowired
    MailConfigService mailConfigService;
    @Autowired
    SendMailHistoryService sendMailHistoryService;
    @Autowired
    MailProperties mailProperties;
    @Autowired
    RedisUtil redisUtil;
    @Value(value = "${ants.minio.bucketName}")
    private String bucketName;
    //模板引擎对象
    @Autowired
    private TemplateEngine templateEngine;

    /**
     * 文章定时发布成功
     *
     * @param map
     */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("sendQuartzPushMessageQueue"))
    public void sendQuartzPushMessageQueue(Map<String, String> map) {
        String addressee = map.get("addressee");
        String title = map.get("title");
        String id = map.get("id");
        String publishTime = map.get("publishTime");
        Context ctx = new Context();
        ctx.setVariable("title", title);
        ctx.setVariable("id", id);
        ctx.setVariable("publishTime", publishTime);
        sendMail(addressee, ctx, "articlePush");
    }

    /**
     * 友联申请
     *
     * @param map
     */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("friendLinksApplyQueue"))
    public void friendLinksApplyQueue(Map<String, String> map) {
        String name = map.get("name");
        String link = map.get("link");
        String webDescribe = map.get("webDescribe");
        Context ctx = new Context();
        ctx.setVariable("name", name);
        ctx.setVariable("link", link);
        ctx.setVariable("webDescribe", webDescribe);
        sendMail("448810587@qq.com", ctx, "friendLinksApply");
    }

    /**
     * 友联申请反馈
     *
     * @param map
     */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("friendLinksApplyFeedbackQueue"))
    public void friendLinksApplyFeedbackQueue(Map<String, String> map) {
        String name = map.get("name");
        String link = map.get("link");
        String webDescribe = map.get("webDescribe");
        String start = map.get("start");
        String feedback = map.get("feedback");
        String email = map.get("email");
        Context ctx = new Context();
        ctx.setVariable("name", name);
        ctx.setVariable("link", link);
        ctx.setVariable("webDescribe", webDescribe);
        ctx.setVariable("start", start);
        ctx.setVariable("feedback", feedback);
        sendMail(email, ctx, "friendLinksApplyFeedback");
    }

    /**
     * 留言
     *
     * @param map
     */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("leavingMessagePushQueue"))
    public void leavingMessagePushQueue(Map<String, String> map) {
        String name = map.get("name");
        String message = map.get("message");
        Context ctx = new Context();
        ctx.setVariable("nickname", name);
        ctx.setVariable("content", message);
        sendMail("448810587@qq.com", ctx, "leavingMessagePush");
    }

    /**
     * 留言回复
     *
     * @param map
     */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("leavingMessageReolyQueue"))
    public void leavingMessageReolyQueue(Map<String, String> map) {
        String name = map.get("name");
        String email = map.get("email");
        String message = map.get("message");
        String nickname = map.get("nickname");
        String content = map.get("content");
        Context ctx = new Context();
        ctx.setVariable("replyname", name);
        ctx.setVariable("replycontent", message);
        ctx.setVariable("nickname", nickname);
        ctx.setVariable("content", content);
        sendMail(email, ctx, "leavingMessageReply");
    }

    /**
     * 留言审核
     *
     * @param map
     */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("leavingMessageCheckQueue"))
    public void leavingMessageCheckQueue(Map<String, String> map) {
        String mail = map.get("mail");
        String status = map.get("status");
        String message = map.get("message");

        LambdaQueryWrapper<MailConfig> lqw = new LambdaQueryWrapper<>();
        lqw.eq(MailConfig::getCreateBy, "chenshuang");
        MailConfig mailConfig = mailConfigService.getOne(lqw);
        Session session = mailProperties.initProperties(mailConfig);

        InputStream inputStream = null;
        try {
            MimeMessage msg = new MimeMessage(session);
            //设置发件人邮箱、发件人名称
            msg.setFrom(new InternetAddress(mailConfig.getUserName(), mailConfig.getNickName(), "UTF-8"));
            //设置收件人邮箱
            msg.setRecipients(Message.RecipientType.TO, mail);
            //设置主题/标题
            msg.setSubject("June 12");
            //设置日期
            msg.setSentDate(new Date());
            //设置正文内容
            Map<String, Object> paras = new HashMap<>();
            paras.put("status", status);
            paras.put("message", message);
            msg.setText(FreemarkerParseFactory.parseTemplate("templates/leavingMessageCheck.ftl", paras), "UTF-8", "html");

            //发送邮件，参数为邮件信息，发件人邮箱和发件人邮箱密码
            Transport.send(msg, mailConfig.getUserName(), mailConfig.getPassword());
        } catch (Exception mex) {
            log.info("Send failed! Exception: " + mex);
            saveMailHistory(mailConfig.getUserName(), "448810587@qq.com", "June 12", "留言发布", null, "失败");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        try {
            saveMailHistory(mailConfig.getUserName(), "448810587@qq.com", "June 12", "留言发布", null, "成功");
        } catch (Exception e) {
            log.error("留言发布！" + e);
        }
    }

    /**
     * 验证码
     *
     * @param addressee
     */
    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("sendCaptchaQueue"))
    public void sendMailCaptchaCode(String addressee) {
        String code = RandomUtil.randomNumbers(4);
        redisUtil.set("captchaCode:" + addressee, code, 60);
        Context ctx = new Context();
        ctx.setVariable("code", code);
        sendMail(addressee, ctx, "sendCaptchaCode");
    }

    private void saveMailHistory(String sender, String addressee, String title, String content, String files, String state) {
        SendMailHistory mailInfo = new SendMailHistory();
        mailInfo.setTitle(title);
        mailInfo.setContent(StrUtil.isNotBlank(content) ? HtmlUtil.cleanHtmlTag(content) : "");
        mailInfo.setAddressee(addressee);
        mailInfo.setSender(sender);
        mailInfo.setFiles(files);
        mailInfo.setState(state);
        sendMailHistoryService.saveOrUpdate(mailInfo);
    }


    @RabbitHandler
    @RabbitListener(queuesToDeclare = @Queue("sendMailQueue"))
    public void sendMailFile(SendMailVo sendMailVo) {
        sendMailFileUtil(sendMailVo);
    }

    /**
     * 发送邮件-带附件
     *
     * @param mailInfo 待发送的邮件信息
     */
    public boolean sendMailFileUtil(SendMailVo mailInfo) {
        LambdaQueryWrapper<MailConfig> lqw = new LambdaQueryWrapper<>();
        lqw.eq(MailConfig::getCreateBy, mailInfo.getCreateBy());
        MailConfig mailConfig = mailConfigService.getOne(lqw);
        Session session = mailProperties.initProperties(mailConfig);
        InputStream inputStream = null;
        String content = StrUtil.isNotBlank(mailInfo.getContent()) ? mailInfo.getContent() : "";
        try {
            MimeMessage msg = new MimeMessage(session);
            //设置发件人邮箱、发件人名称
            msg.setFrom(new InternetAddress(mailConfig.getUserName(), mailConfig.getNickName(), "UTF-8"));
            //设置收件人邮箱
            msg.setRecipients(Message.RecipientType.TO, mailInfo.getAddressees());
            //设置主题/标题
            msg.setSubject(mailInfo.getTitle());
            //设置日期
            msg.setSentDate(new Date());

            //设置正文内容
            Map<String, Object> paras = new HashMap<>();
            paras.put("content", content);
            msg.setText(FreemarkerParseFactory.parseTemplate("templates/mailTools.ftl", paras), "UTF-8", "html");

            //向multipart对象中添加邮件的各个部分内容，包括文本内容和附件
            MimeMultipart multipart = new MimeMultipart();
            BodyPart contentPart = new MimeBodyPart();
            contentPart.setContent(FreemarkerParseFactory.parseTemplate("templates/mailTools.ftl", paras), "text/html;charset=UTF-8");
            multipart.addBodyPart(contentPart);

            multipart.setSubType("mixed");
            //添加附件
            MimeBodyPart filePart = null;
            if (mailInfo.getUploadFile() != null && mailInfo.getUploadFile().split(",").length > 0) {
                for (String filePath : mailInfo.getUploadFile().split(",")) {
                    inputStream = null;
                    filePart = new MimeBodyPart();
                    //inputStream = readLocalFile(filePath);
                    inputStream = MinioUtil.getMinioFile(bucketName, filePath.replace("https://www.wxmin.cn:9000/ants-file/", ""));
                    byte[] bytes = IOUtils.toByteArray(inputStream);
                    //添加附件的内容
                    filePart.setDataHandler(new DataHandler(new ByteArrayDataSource(bytes, "application/octet-stream")));
                    //添加附件的标题
                    filePart.setFileName(MimeUtility.encodeWord(filePath.replace("https://www.wxmin.cn:9000/ants-file/ants-mailFile/", "")));
                    multipart.addBodyPart(filePart);
                }
                //将multipart对象放到message中
                msg.setContent(multipart);
            }

            //发送邮件，参数为邮件信息，发件人邮箱和发件人邮箱密码
            Transport.send(msg, mailConfig.getUserName(), mailConfig.getPassword());
        } catch (Exception mex) {
            log.info("Send failed! Exception: " + mex);
            saveMailHistory(mailConfig.getUserName(), mailInfo.getAddressees(), mailInfo.getTitle(), content, mailInfo.getUploadFile(), "失败");
            return false;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        try {
            saveMailHistory(mailConfig.getUserName(), mailInfo.getAddressees(), mailInfo.getTitle(), content, mailInfo.getUploadFile(), "成功");
        } catch (Exception e) {
            log.error("保存邮件发送记录失败！" + e);
        }
        return true;
    }


    private void sendMail(String addressee, Context ctx, String templateName) {
        LambdaQueryWrapper<MailConfig> lqw = new LambdaQueryWrapper<>();
        lqw.eq(MailConfig::getCreateBy, "chenshuang");
        MailConfig mailConfig = mailConfigService.getOne(lqw);
        Session session = mailProperties.initProperties(mailConfig);

        InputStream inputStream = null;

        String text = "";
        try {
            MimeMessage msg = new MimeMessage(session);
            //设置发件人邮箱、发件人名称
            msg.setFrom(new InternetAddress(mailConfig.getUserName(), mailConfig.getNickName(), "UTF-8"));
            //设置收件人邮箱
            msg.setRecipients(Message.RecipientType.TO, addressee);
            //设置主题/标题
            msg.setSubject("June 12");
            //设置日期
            msg.setSentDate(new Date());
            //设置正文内容

            // 使用TemplateEngine 对模版进行渲染
            text = templateEngine.process(templateName, ctx);
            msg.setText(text, "UTF-8", "html");


            //发送邮件，参数为邮件信息，发件人邮箱和发件人邮箱密码
            Transport.send(msg, mailConfig.getUserName(), mailConfig.getPassword());
        } catch (Exception mex) {
            log.info("Send failed! Exception: " + mex);
            saveMailHistory(mailConfig.getUserName(), addressee, "June 12", text, null, "失败");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }
        }
        try {
            saveMailHistory(mailConfig.getUserName(), addressee, "June 12", text, null, "成功");
        } catch (Exception e) {
            log.error("留言发布！" + e);
        }
    }

}
